package com.zzqstart.cateservice.service.impl;

import cn.hutool.core.util.ArrayUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zzqstart.cateservice.controller.remote.consume.UcenRemoteController;
import com.zzqstart.cateservice.entity.*;
import com.zzqstart.commonutils.entity.RecipeDetailFrontVo;
import com.zzqstart.commonutils.entity.VariableObj;
import com.zzqstart.cateservice.entity.vo.*;
import com.zzqstart.cateservice.mapper.CateRecipeMapper;
import com.zzqstart.cateservice.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzqstart.commonutils.entity.UcenterMember;
import com.zzqstart.servicebase.exceptionhandler.CateException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author testjava
 * @since 2023-03-06
 */
@Service
public class CateRecipeServiceImpl extends ServiceImpl<CateRecipeMapper, CateRecipe> implements CateRecipeService {

    @Autowired
    private CateCategoryService cateCategoryService;

    @Autowired
    private CateRecipeDetailService cateRecipeDetailService;

    @Autowired
    private CateVideoService cateVideoService;

    @Autowired
    private UcenRemoteController ucenRemoteController;

    @Autowired
    private CateRecipeService cateRecipeService;

    @Autowired
    private CateGradeService cateGradeService;

    @Override
    public List<CateRecipe> getIndexRecipeList() {
        QueryWrapper<CateRecipe> recipeQueryWrapper = new QueryWrapper<>();
        recipeQueryWrapper.orderByDesc("create_time");
        recipeQueryWrapper.last("limit 8");
        List<CateRecipe> list = baseMapper.selectList(recipeQueryWrapper);
        return list;
    }

    @Override
    public Map<String, Object> getRecipeFrontList(Long page, Long limit, RecipeQueryVo recipeQueryVo) {
        QueryWrapper<CateRecipe> wrapper = new QueryWrapper<>();

        if (recipeQueryVo != null) {
            // 一级菜单封装查询条件
            if (!StringUtils.isEmpty(recipeQueryVo.getCategoryParentId())) {
                wrapper.eq("category_parent_id", recipeQueryVo.getCategoryParentId());
                // 二级菜单封装查询条件
                if (!StringUtils.isEmpty(recipeQueryVo.getCategoryId())) {
                    wrapper.eq("category_id", recipeQueryVo.getCategoryId());
                }
            }
            // 添加查询条件
            if (recipeQueryVo.getCreateTime()) {
                wrapper.orderByDesc("create_time");
            }

            if (recipeQueryVo.getCollect()) {
                wrapper.orderByDesc("collect_count");
            }

            if (recipeQueryVo.getGrade()) {
                wrapper.orderByDesc("grade");
            }
        }
        // 分页
        Page<CateRecipe> recipePage = new Page<>(page, limit);
        baseMapper.selectPage(recipePage, wrapper);

        // 获取数据
        List<CateRecipe> list = recipePage.getRecords();
        long total = recipePage.getTotal();
        long current = recipePage.getCurrent();

        // 放入将返回的map中
        Map<String, Object> map = new HashMap<>();
        // 查询的数据
        map.put("list", list);
        // 总数据数
        map.put("total", total);
        // 当前页
        map.put("current", current);

        return map;
    }

    @Override
    @Transactional
    public boolean publishRecipe(PublishRecipeVo createRecipeVo) {

        System.out.println(createRecipeVo);

        CateRecipe cateRecipe = new CateRecipe();
        BeanUtils.copyProperties(createRecipeVo, cateRecipe);
        boolean isChange = cateRecipeService.saveOrUpdate(cateRecipe);
        if (!isChange) {
            throw new CateException(20001, "菜谱基本信息插入数据库失败");
        }

        String recipeId = cateRecipe.getId();

        CateRecipeDetail cateRecipeDetail = new CateRecipeDetail();
        BeanUtils.copyProperties(createRecipeVo, cateRecipeDetail);

        // 前台数组封装成字符串
        VariableObj[] mainFoodVar = createRecipeVo.getMainFood();
        String mainFood = arrayToString(mainFoodVar,",");

        VariableObj[] secondaryFoodFront = createRecipeVo.getSecondaryFood();
        String secondaryFood = arrayToString(secondaryFoodFront,",");

        VariableObj[] seasoningFront = createRecipeVo.getSeasoning();
        String seasoning = arrayToString(seasoningFront,",");

        VariableObj[] stepFront = createRecipeVo.getStep();
        String step = arrayToString(stepFront, "&cate&");

        String[] imgUrlFront = createRecipeVo.getImgUrl();
        String imgUrl = ArrayUtil.join(imgUrlFront, ",");

        cateRecipeDetail.setMainFood(mainFood);
        cateRecipeDetail.setSecondaryFood(secondaryFood);
        cateRecipeDetail.setSeasoning(seasoning);
        cateRecipeDetail.setStep(step);
        cateRecipeDetail.setImgUrl(imgUrl);
        cateRecipeDetail.setId(recipeId);

        boolean saveCateRecipeDetail = cateRecipeDetailService.saveOrUpdate(cateRecipeDetail);
        if (!saveCateRecipeDetail) {
            throw new CateException(20001, "菜谱详细信息插入数据库失败");
        }

        CateVideo cateVideo = new CateVideo();
        cateVideo.setRecipeId(recipeId);
        BeanUtils.copyProperties(createRecipeVo, cateVideo);
        boolean saveCateVideo = cateVideoService.saveOrUpdate(cateVideo);
        if (!saveCateVideo) {
            throw new CateException(20001, "菜谱视频信息插入数据库失败");
        }

        return true;
    }

    private String arrayToString(VariableObj[] objList,String regex){
        StringBuilder builder = new StringBuilder();

        for (int i = 0; i < objList.length; i++) {
            String value = objList[i].getValue();
            if (i==0){
                builder.append(value);
                continue;
            }
            builder.append(regex+value);
        }
        return new String(builder);
    }

    @Override
    public RecipeDetailFrontVo getRecipeDetailById(String recipeId) {

        if (StringUtils.isEmpty(recipeId)) {
            new CateException(20001, "菜单Id为空！！！");
        }

        RecipeDetailFrontVo recipeDetailFrontVo = new RecipeDetailFrontVo();
        // recipe表信息
        CateRecipe recipe = baseMapper.selectById(recipeId);

        String publisherId = recipe.getPublisherId();
        UcenterMember member = ucenRemoteController.getMemberInfoByMemberId(publisherId);
        BeanUtils.copyProperties(member, recipeDetailFrontVo);

        // 与cateRecipeId一样
        CateRecipeDetail recipeDetail = cateRecipeDetailService.getById(recipeId);

        // 视频数据
        QueryWrapper<CateVideo> videoQueryWrapper = new QueryWrapper<>();
        videoQueryWrapper.eq("recipe_id", recipeId);
        CateVideo video = cateVideoService.getOne(videoQueryWrapper);

        BeanUtils.copyProperties(recipe, recipeDetailFrontVo);
        BeanUtils.copyProperties(recipeDetail, recipeDetailFrontVo);
        BeanUtils.copyProperties(video, recipeDetailFrontVo);

        // 不能用BeanUtils的数据手动安装
        String mainFoodStr = recipeDetail.getMainFood();
        String[] mainFoodArray = mainFoodStr.split(",");

        String secondaryFoodStr = recipeDetail.getSecondaryFood();
        String[] secondaryFoodArray = secondaryFoodStr.split(",");

        String seasoningStr = recipeDetail.getSeasoning();
        String[] seasoningArray = seasoningStr.split(",");

        String step = recipeDetail.getStep();
        String[] stepArray = step.split("&cate&");

        String imgUrlStr = recipeDetail.getImgUrl();
        String[] imgUrlArray = imgUrlStr.split(",");

        recipeDetailFrontVo.setMainFood(mainFoodArray);
        recipeDetailFrontVo.setSecondaryFood(secondaryFoodArray);
        recipeDetailFrontVo.setSeasoning(seasoningArray);

        Map<String, String>[] mapArray = new HashMap[imgUrlArray.length];

        for (int i = 0; i < mapArray.length; i++) {
            HashMap<String, String> map = new HashMap<>();
            map.put("step", stepArray[i]);
            map.put("imgUrl", imgUrlArray[i]);
            mapArray[i] = map;
        }

        recipeDetailFrontVo.setStepAndImg(mapArray);
        return recipeDetailFrontVo;
    }

    @Override
    public PublishRecipeVo getRecipePublishInfoById(String recipeId) {
        if (StringUtils.isEmpty(recipeId)) {
            new CateException(20001, "菜单Id为空！！！");
        }

        PublishRecipeVo recipeFrontVo = new PublishRecipeVo();
        // recipe表信息
        CateRecipe recipe = baseMapper.selectById(recipeId);
        BeanUtils.copyProperties(recipe,recipeFrontVo);
        // 与cateRecipeId一样
        CateRecipeDetail recipeDetail = cateRecipeDetailService.getById(recipeId);
        BeanUtils.copyProperties(recipeDetail,recipeFrontVo);

        // 视频数据
        QueryWrapper<CateVideo> videoQueryWrapper = new QueryWrapper<>();
        videoQueryWrapper.eq("recipe_id", recipeId);
        CateVideo video = cateVideoService.getOne(videoQueryWrapper);
        BeanUtils.copyProperties(video,recipeFrontVo);

        // 不能用BeanUtils的数据手动安装
        String mainFoodStr = recipeDetail.getMainFood();
        VariableObj[] mainFoodObjList = strToArray(mainFoodStr,",");
        recipeFrontVo.setMainFood(mainFoodObjList);

        String secondaryFoodStr = recipeDetail.getSecondaryFood();
        VariableObj[] secondaryFoodObjList = strToArray(secondaryFoodStr,",");
        recipeFrontVo.setSecondaryFood(secondaryFoodObjList);

        String seasoningStr = recipeDetail.getSeasoning();
        VariableObj[] seasoningObjList = strToArray(seasoningStr,",");
        recipeFrontVo.setSeasoning(seasoningObjList);

        String step = recipeDetail.getStep();
        VariableObj[] stepObjList = strToArray(step,"&cate&");
        recipeFrontVo.setStep(stepObjList);

        String imgUrlStr = recipeDetail.getImgUrl();
        String[] imgUrlArray = imgUrlStr.split(",");
        recipeFrontVo.setImgUrl(imgUrlArray);

        return recipeFrontVo;
    }

    public VariableObj[] strToArray(String str,String regex){
        String[] strList = str.split(regex);
        VariableObj[] array = new VariableObj[strList.length];
        for (int i = 0; i < strList.length; i++) {
            VariableObj obj = new VariableObj();
            obj.setValue(strList[i]);
            array[i] = obj;
        }
        return array;
    }

    @Override
    public Map<String, Object> getRecipeListByMemberId(Long page, Long limit, RecipeQueryVo recipeQueryVo) {
        QueryWrapper<CateRecipe> wrapper = new QueryWrapper<>();
        if (recipeQueryVo != null) {

            if (!StringUtils.isEmpty(recipeQueryVo.getIsReturn()) && recipeQueryVo.getIsReturn()) {
                wrapper.eq("is_return", 1);
            }

            if (!StringUtils.isEmpty(recipeQueryVo.getPublisherId())) {
                wrapper.eq("publisher_id", recipeQueryVo.getPublisherId());
            }
            // 添加查询条件
            if (recipeQueryVo.getCreateTime()) {
                wrapper.orderByDesc("create_time");
            }

            if (recipeQueryVo.getCollect()) {
                wrapper.orderByDesc("collect_count");
            }

            if (recipeQueryVo.getGrade()) {
                wrapper.orderByDesc("grade");
            }
        }
        // 分页
        Page<CateRecipe> recipePage = new Page<>(page, limit);
        baseMapper.selectPage(recipePage, wrapper);

        // 获取数据
        List<CateRecipe> list = recipePage.getRecords();
        long total = recipePage.getTotal();
        long current = recipePage.getCurrent();

        // 放入将返回的map中
        Map<String, Object> map = new HashMap<>();
        // 查询的数据
        map.put("list", list);
        // 总数据数
        map.put("total", total);

        return map;
    }

    @Override
    public Map<String, Object> pageBySearch(long page, long limit, String inputValue) {
        Page<CateRecipe> objectPage = new Page<>(page, limit);
        QueryWrapper<CateRecipe> wrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(inputValue)) {
            wrapper.like("title", inputValue);
        }
        baseMapper.selectPage(objectPage, wrapper);
        List<CateRecipe> list = objectPage.getRecords();
        long total = objectPage.getTotal();
        long size = objectPage.getSize();
        HashMap<String, Object> map = new HashMap<>();

        map.put("list", list);
        map.put("total", total);
        map.put("size", size);
        return map;
    }

    @Override
    public Map<String, Object> getRecipeBySearchObj(long page, long limit, BackRecipeQuery cateRecipe) {
        Page<CateRecipe> pageObj = new Page<>(page, limit);
        QueryWrapper<CateRecipe> wrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(cateRecipe)) {

            String categoryParentId = cateRecipe.getCategoryParentId();
            String categoryId = cateRecipe.getCategoryId();
            String publisherName = cateRecipe.getPublisherName();
            BigDecimal gradeleft = cateRecipe.getGradeLeft();
            BigDecimal graderight = cateRecipe.getGradeRight();
            Boolean isCreateTime = cateRecipe.getIsCreateTime();
            Integer isDeleted = cateRecipe.getIsDeleted();
            String title = cateRecipe.getTitle();
            Integer isReturn = cateRecipe.getIsReturn();

            if (!StringUtils.isEmpty(isReturn)) {
                wrapper.eq("is_return", isReturn);
            }

            if (!StringUtils.isEmpty(categoryParentId)) {
                wrapper.eq("category_id", categoryParentId);
                if (!StringUtils.isEmpty(categoryId)) {
                    wrapper.eq("category_id", categoryId);
                }
            }

            if (!StringUtils.isEmpty(categoryParentId)) {
                wrapper.eq("category_id", categoryParentId);
                if (!StringUtils.isEmpty(categoryId)) {
                    wrapper.eq("category_id", categoryId);
                }
            }

            if (!StringUtils.isEmpty(publisherName)) {
                String publisherId = ucenRemoteController.getMemberIdByMemberName(publisherName);
                wrapper.eq("publisher_id", publisherId);
            }

            if (!StringUtils.isEmpty(gradeleft)) {
                wrapper.ge("grade", gradeleft);
            }

            if (!StringUtils.isEmpty(graderight)) {
                wrapper.gt("grade", graderight);
            }

            if (!StringUtils.isEmpty(isCreateTime) && isCreateTime) {
                wrapper.orderByDesc("create_time");
            }

            if (!StringUtils.isEmpty(cateRecipe.getTime())){
                wrapper.le("create_time",cateRecipe.getTime());
            }

            if (!StringUtils.isEmpty(isDeleted)) {
                wrapper.eq("is_deleted", isDeleted);
            }

            if (!StringUtils.isEmpty(title)) {
                wrapper.like("title", title);
            }
        }

        baseMapper.selectPage(pageObj, wrapper);

        long total = pageObj.getTotal();
        List<CateRecipe> list = pageObj.getRecords();
        List<CateCategory> categoryList = cateCategoryService.getAllCategory();

        HashMap<String, String> categoryAllMap = new HashMap<>();
        for (CateCategory cateCategory : categoryList) {
            categoryAllMap.put(cateCategory.getId(), cateCategory.getTitle());
        }

        ArrayList<CateRecipeVo> resultList = new ArrayList<>();

        for (CateRecipe recipe : list) {
            CateRecipeVo cateRecipeVo = new CateRecipeVo();
            UcenterMember member = ucenRemoteController.getMemberInfoByMemberId(recipe.getPublisherId());
            String nickname = member.getNickname();
            Integer isChef = member.getIsChef();
            cateRecipeVo.setPublisherName(nickname);
            cateRecipeVo.setIsChef(isChef);

            BeanUtils.copyProperties(recipe, cateRecipeVo);
            if (!StringUtils.isEmpty(recipe.getCategoryParentId())) {

                String categoryParentId = recipe.getCategoryParentId();
                String categoryParentName = categoryAllMap.get(categoryParentId);
                cateRecipeVo.setCategoryParentName(categoryParentName);

                if (!StringUtils.isEmpty(recipe.getCategoryId())) {
                    String categoryId = recipe.getCategoryId();
                    String categoryName = categoryAllMap.get(categoryId);
                    cateRecipeVo.setCategoryName(categoryName);
                }
            }
            resultList.add(cateRecipeVo);
        }

        long size = pageObj.getSize();

        HashMap<String, Object> map = new HashMap<>();

        map.put("total", total);
        map.put("list", resultList);
        map.put("size", size);

        return map;
    }

    @Override
    @Transactional
    public boolean markRecipe(String recipeId, BigDecimal grade,String memberId) {
        CateGrade cateGrade = new CateGrade();
        cateGrade.setRecipeId(recipeId);
        cateGrade.setMemberId(memberId);
        cateGrade.setGrade(grade);
        boolean saveGradeTable = cateGradeService.save(cateGrade);

        CateRecipe recipe = baseMapper.selectById(recipeId);
        BigDecimal gradeDB = recipe.getGrade();
        Integer gradeCountDB = recipe.getGradeCount();

        BigDecimal newGradeDB = null;
        Integer newGradeCount = gradeCountDB+1;

        if (gradeDB.equals(0)){
            newGradeDB.add(grade);
        }else {
            newGradeDB = gradeDB.multiply(BigDecimal.valueOf(gradeCountDB))
                    .add(grade)
                    .divide(BigDecimal.valueOf(newGradeCount),BigDecimal.ROUND_CEILING);
        }

        CateRecipe newRecipe = new CateRecipe();
        newRecipe.setGrade(newGradeDB);
        newRecipe.setGradeCount(newGradeCount);
        newRecipe.setId(recipeId);

        int update = baseMapper.updateById(newRecipe);
        return update>0 && saveGradeTable;
    }

    @Override
    public String getPublishNameByRecipeId(String recipeId) {
        QueryWrapper<CateRecipe> wrapper = new QueryWrapper<>();
        wrapper.eq("id",recipeId);
        wrapper.select("title");
        CateRecipe cateRecipe = baseMapper.selectOne(wrapper);
        String title = cateRecipe.getTitle();

        return title;
    }

    @Override
    public Map<String, Object> getCollectRecipeByMemberId(Long page, Long limit, List<String> recipeIdList) {
        Page<CateRecipe> objectPage = new Page<>(page, limit);
        QueryWrapper<CateRecipe> wrapper = new QueryWrapper<>();
        wrapper.in("id",recipeIdList);
        baseMapper.selectPage(objectPage,wrapper);
        List<CateRecipe> list = objectPage.getRecords();
        long total = objectPage.getTotal();
        long size = objectPage.getSize();
        HashMap<String, Object> map = new HashMap<>();

        map.put("list", list);
        map.put("total", total);
        map.put("size", size);
        return map;
    }

}
